module OPayXCConfigPlugin
    class OPayXCConfigFile
    
      COMMON_CONFIG_KEY = :GZC_XCCONFIG_COMMON_CONFIG_KEY
    
      def initialize
        @configuration_dict = Hash.new { |h, k| h[k] = OPayXCConfigInfo.new }
      end
    
      def load_config(config_file_path)
        config_file_info = _load_config_file config_file_path
        merge config_file_info
      end
    
      def common_config
        @configuration_dict[COMMON_CONFIG_KEY]
      end
    
      def config_with_type(type)
        @configuration_dict[type]
      end
    
      def final_config_with_type(type)

        common_config_info = common_config.clone
        specific_config_info = config_with_type(type).clone
        common_config_info.merge specific_config_info
        common_config_info
      end
    
      def config_info_dict
        @configuration_dict
      end
    
      def merge(another_file_config)
        another_file_config.config_info_dict.each do |name, config|
          @configuration_dict[name].merge config
        end
      end
    
      def to_s
        @configuration_dict.to_s
      end
    
      private
    
      def _load_config_file(file_path)
        raise "#{file_path} unreadable" unless File.readable? file_path
    
        config_file = OPayXCConfigFile.new
    
        File.open(file_path, 'r') do |xcconfig_file|
          xcconfig_file.each_line do |line|
    
            ret = (/^\/\/.*/ =~ line)
            next unless ret.nil?
            next unless line != "\n"
    
            is_macro = true
    
            line_data = if line =~ /[^= ]*\[.*\]\s*=.*/
                          /\s*(?<key>[^= ]*\s*\[.*\])\s*\|=\s*(?<value>.*)\s*/.match line
                        else
                          /\s*(?<key>[^= ]*)\s*\|=\s*(?<value>.*)\s*/.match line
                        end
    
            if line_data.nil?
    
              line_data = if line =~ /[^= ]*\[.*\]\s*=.*/
                            /\s*(?<key>[^= ]*\s*\[.*\])\s*=\s*(?<value>.*)\s*/.match line
                          else
                            /\s*(?<key>[^= ]*)\s*=\s*(?<value>.*)\s*/.match line
                          end
    
              is_macro = false
            end
    
            raise "syntax error1 in #{file_path}:#{line}" if line_data.nil?
    
            key = line_data['key']
            value = line_data['value']
            raise "syntax error1 in #{file_path}:#{line}" if key.nil?
            raise "syntax error1 in #{file_path}:#{line}" if value.nil?
    
            if key =~ /\[.*config\s*=\s*.*\]/
    
              matched = /(?<key>.*)\[\s*(?<property>.*)\s*\]/.match(key)
              raise "syntax error2 in #{file_path}:#{line}" if matched.nil?
    
              key = matched['key']
              property_string = matched['property']
              raise "syntax error3 in #{file_path}:#{line}" if key.nil?
              raise "syntax error4 in #{file_path}:#{line}" if property_string.nil?
    
              new_property_list = []
              property_list = property_string.split(/\s*,\s*/)
              property_list.each do |property|
                unless property.start_with? 'config'
                  new_property_list.push property
                  next
                end
    
                config_property = property.split(/\s*=\s*/)
                raise "syntax error5 in #{file_path}:#{line}" if config_property.length != 2
                raise "syntax error6 in #{file_path}:#{line}" if config_property[0] != 'config'
    
                config_string = config_property[1]
                all_config_name = config_string.split(/\s*\|\s*/)
                all_config_name.each do |config_name|
                  config = config_file.config_with_type(config_name)
    
                  key = "#{key}#{new_property_list.empty? ? '' : "[#{new_property_list.join(',')}]"}"
                  if is_macro
                    config.add_macro(key, value)
                  else
                    config.add_env(key, value)
                  end
                end
              end
    
            else
              config = config_file.common_config
              if is_macro
                config.add_macro(key, value)
              else
                config.add_env(key, value)
              end
            end
          end
        end
        config_file
      end
    end
    end